package com.maybach.core.manager.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.media.MediaConfiguration;
import com.alibaba.media.Result;
import com.alibaba.media.upload.UploadPolicy;
import com.alibaba.media.upload.UploadRequest;
import com.alibaba.media.upload.UploadResponse;
import com.alibaba.media.upload.UploadTokenClient;
import com.alibaba.media.upload.impl.DefaultUploadClient;
import com.alibaba.media.upload.impl.DefaultUploadTokenClient;
import com.maybach.core.manager.ImageManager;
import com.maybach.redis.IRedisRepository;
import com.qiniu.api.auth.AuthException;
import com.qiniu.api.auth.digest.Mac;
import com.qiniu.api.config.Config;
import com.qiniu.api.fop.ImageInfo;
import com.qiniu.api.fop.ImageInfoRet;
import com.qiniu.api.io.IoApi;
import com.qiniu.api.io.PutExtra;
import com.qiniu.api.io.PutRet;
import com.qiniu.api.rs.PutPolicy;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Created by pyshift on 15/9/23.
 */
@Component
public class ImageManagerImpl implements ImageManager {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    private final static String IMG_TMP = "/tmp/";

    private String wantuToken = "wantuToken";//顽兔的上传token


    /**
     * 七牛图片 密钥 图片地址
     */
    public final static String IMG_PREFIX = "https://dn-mhc.qbox.me/";
    private final static String ACCESS_KEY = "BzDkpyEeUNKVhvJn5spXnnwzQXYBnS034DXkbP3U";
    private final static String SECRET_KEY = "tZBXqnjKq4SpTyGtH_W2yQJh_mfBJCpsf1aKDk2P";

    /**
     * 顽兔 密钥 和 空间名称
     * 配置图片服务的AK: AccessKey、AccessKeySecret
     * 配置图片服务的namespace:
     */
    private final static String AK = "23243188";
    private final static String SK = "3ce8dee1f4f591185252bb62b834f4aa";
    private final static String NAMESPACE = "maihaoche";
    private final static String WT_IMG_PREFIX = "http://maihaoche.image.alimmdn.com/";


    public String uploadFileByWt(FileItem fileItem) {
        if (fileItem == null) {
            return "";
        }

        String extension = getExtension(fileItem.getName());
        String key = UUID.randomUUID().toString().toUpperCase() + extension;
        File file = new File("");

        return uploadFileByWT(key, file);
    }

    public String uploadFile(FileItem fileItem) {
        if (fileItem == null) {
            return "";
        }
        String key = UUID.randomUUID().toString().toUpperCase() + getExtension(fileItem.getName());
        try {
            File file = new File(IMG_TMP + key);
            saveTmp(fileItem.getInputStream(), IMG_TMP + key);
            return uploadFileByQN(key, file);
        } catch (Exception e) {

        } finally {
            deleteTmp(IMG_TMP + key, true);
        }
        return "";
    }

    public String uploadFile(byte[] bytes) {
        return uploadFile(bytes, ".jpg");
    }


    public String uploadFile(byte[] bytes, String extension) {
        if (bytes == null) {
            return "";
        }
        if (StringUtils.isBlank(extension)) {
            extension = ".jpg";
        }
        String key = UUID.randomUUID().toString().toUpperCase() + extension;
        try {
            File file = new File(IMG_TMP + key);
            saveTmp(bytes, IMG_TMP + key);
            return uploadFileByQN(key, file);
        } catch (Exception e) {

        } finally {
            deleteTmp(IMG_TMP + key, true);
        }
        return "";
    }

    public String getShuiUrl(Integer type, String url) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        String shuiUrl = "";
        if (type == 1) {//外观用黑色
            shuiUrl = url + "?watermark/1/image/aHR0cDovL2ltZy5tYWloYW9jaGUuY29tL3NodWlfeGlhb19oZWkucG5n/dissolve/50/gravity/SouthEast";
        } else if (type == 0) {//内饰用白色
            shuiUrl = url + "?watermark/1/image/aHR0cDovL2ltZy5tYWloYW9jaGUuY29tL3NodWlfeGlhby5wbmc=/dissolve/50/gravity/SouthEast";
        } else {
            return url;
        }
        String key = UUID.randomUUID().toString().toUpperCase() + getExtension(url);
        try {
            URL picUrl = new URL(shuiUrl);
            File file = new File(IMG_TMP + key);
            saveTmp(picUrl.openStream(), IMG_TMP + key);
            return uploadFileByQN(key, file);
        } catch (Exception e) {

        } finally {
            deleteTmp(IMG_TMP + key, true);
        }
        return "";
    }

    public static Map getSize(String url) {
        Map m = new HashMap();
        ImageInfoRet ret = ImageInfo.call(url);
        m.put("height", ret.height);
        m.put("width", ret.width);
        return m;
    }

    /**
     * 顽兔上传文件
     *
     * @param key  key值
     * @param file 文件
     * @return
     */
    private String uploadFileByWT(String key, File file) {
        UploadRequest uploadRequest = new UploadRequest(getTokenByWT());
        uploadRequest.setFile(file);
        uploadRequest.setName(key);
        Result<UploadResponse> result = new DefaultUploadClient().upload(uploadRequest);
        if (result.isSuccess()) {
            return result.getData().getUrl();
        } else {
            log.warn(JSON.toJSONString(result));
        }
        return "";
    }

    /**
     * 七牛上传文件
     *
     * @param key  key值
     * @param file 文件
     * @return
     */
    private String uploadFileByQN(String key, File file) {
        PutRet ret = IoApi.putFile(getUpToken(), key, file, new PutExtra());
        if (StringUtils.isBlank(ret.getKey())) {
            return "";
        }
        return IMG_PREFIX + ret.getKey();
    }


    /**
     * 根据文件名 获取文件的后缀名
     *
     * @param fileUrl
     * @return
     */
    private static String getExtension(String fileUrl) {
        if (StringUtils.isBlank(fileUrl)) {
            return ".jpg";
        }
        return fileUrl.substring(fileUrl.lastIndexOf("."), fileUrl.length());
    }


    private void saveTmp(InputStream is, String fileName) {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        FileOutputStream fileOutStream = null;
        byte[] buffer = new byte[1024];
        int len = 0;
        try {
            while ((len = is.read(buffer)) != -1) {
                outStream.write(buffer, 0, len);
            }

            byte[] data = outStream.toByteArray();
            File imageFile = new File(fileName);
            fileOutStream = new FileOutputStream(imageFile);
            fileOutStream.write(data);
        } catch (IOException e) {

        } finally {
            try {
                outStream.close();
            } catch (IOException e) {
            }
            if (fileOutStream != null) {
                try {
                    fileOutStream.close();
                } catch (IOException e) {
                }
            }
            try {
                is.close();
            } catch (IOException e) {
            }
        }
    }

    private void saveTmp(byte[] bytes, String fileName) {
        FileOutputStream fileOutStream = null;
        try {
            File imageFile = new File(fileName);
            fileOutStream = new FileOutputStream(imageFile);
            fileOutStream.write(bytes);
        } catch (IOException e) {

        } finally {
            if (fileOutStream != null) {
                try {
                    fileOutStream.close();
                } catch (IOException e) {
                }
            }
        }
    }

    private void deleteTmp(final String fileName, final boolean isQiniu) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                if (StringUtils.isBlank(fileName) || fileName.length() <= IMG_TMP.length()) {
                    return;
                }
                if (isQiniu) {
                    uploadFileByWT(fileName.substring(IMG_TMP.length(), fileName.length()), new File(fileName));
                } else {
                    uploadFileByQN(fileName.substring(IMG_TMP.length(), fileName.length()), new File(fileName));
                }
                File file = new File(fileName);
                if (file.exists() && file.isFile()) {
                    file.delete();
                }
            }
        });
        t.start();
    }


    /**
     * 初始化 MediaConfiguration
     * 长传策略为
     * 用户上传文件允许覆盖
     * 该用户凭证的失效时间为当前时间之后的一个小时, 在之后的一个小时之内Token都可以作为用户的上传凭证
     * 失效时间设置为-1时表示永不失效
     *
     * @return Token
     */
    public String getTokenByWT() {
        String token = redisRepository.get(wantuToken, String.class);
        if (StringUtils.isNotBlank(token)) {
            return token;
        }
        MediaConfiguration configuration = new MediaConfiguration();
        configuration.setType(MediaConfiguration.TYPE_TOP);
        configuration.setAk(AK);
        configuration.setSk(SK);
        configuration.setNamespace(NAMESPACE);
        UploadTokenClient tokenClient = new DefaultUploadTokenClient(configuration);

        UploadPolicy uploadPolicy = new UploadPolicy();
        uploadPolicy.setInsertOnly(UploadPolicy.INSERT_ONLY_NONE);
        uploadPolicy.setExpiration(System.currentTimeMillis() + 3600 * 1000);
        String uploadToken = tokenClient.getUploadToken(uploadPolicy);
        try {
            redisRepository.set(wantuToken, uploadToken, 3600);
        } catch (Exception e) {
        }
        return uploadToken;
    }

    /**
     * 七牛上传token
     *
     * @return
     * @throws AuthException
     */
    public String getUpToken() {
        Config.ACCESS_KEY = ACCESS_KEY;
        Config.SECRET_KEY = SECRET_KEY;

        Mac mac = new Mac(Config.ACCESS_KEY, Config.SECRET_KEY);

        String bucketName = "maihaoche";
        PutPolicy putPolicy = new PutPolicy(bucketName);
        try {
            return putPolicy.token(mac);
        } catch (Exception e) {

        }
        return "";
    }


    @Autowired
    private IRedisRepository redisRepository;
}
